<template>
  <div id="canvas"></div>
</template>

<script>
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
export default {
  name: 'Editor',
  data() {
    return {
      inited: false,
      content: '',
      scene: null,
      camera: null,
      renderer: null,
      mesh: null,
      setting: null,
      cube: null,
      light: null,
      controls: null
    };
  },
  mounted() {
    // this.scene = new Scene()
    // this.camera = new PerspectiveCamera(
    //   75,
    //   window.innerWidth / window.innerHeight,
    //   0.1,
    //   1000
    // )
    // this.renderer = new WebGLRenderer({ antialias: true })
    // this.renderer.setSize(400, 400)
    // const $canvas = document.getElementById('canvas')
    // // console.log($canvas, this.renderer.domElement)
    // // $canvas.innerHTML = this.renderer.domElement.outerHTML
    // // document.body.appendChild(this.renderer.domElement)
    // if (!this.inited) {
    //   $canvas.appendChild(this.renderer.domElement)
    //   this.inited = true
    // }
    // window.addEventListener('resize', () => this.onWindowResize())
    // const textureLoader = new TextureLoader()
    // const boxTexture = textureLoader.load('../assets/images/box.jpg')
    // const boxGeometry = new BoxGeometry(1, 1, 1)
    // const meshBasicMaterial = new MeshBasicMaterial({ color: 'red' })
    // // const meshBasicMaterial = new MeshBasicMaterial({ map: boxTexture })
    // const mesh = new Mesh(boxGeometry, meshBasicMaterial)
    // mesh.name = 'box'
    // this.camera.position.set(0, 0, 5)
    // this.scene.add(mesh)
    // new OrbitControls(this.camera, this.renderer.domElement)
    // this.render()
  },
  created() {
    if (!this.inited) {
      this.draw();
      this.inited = true;
    }
  },
  methods: {
    // 初始化render
    initRender() {
      this.renderer = new THREE.WebGLRenderer({ antialias: true });
      this.renderer.setSize(window.innerWidth, window.innerHeight);
      //告诉渲染器需要阴影效果
      this.renderer.shadowMap.enabled = true;
      this.renderer.shadowMap.type = THREE.PCFSoftShadowMap; // 默认的是，没有设置的这个清晰 THREE.PCFShadowMap
      document.body.appendChild(this.renderer.domElement);
    },
    //   初始化相机
    initCamera() {
      this.camera = new THREE.PerspectiveCamera(
        45,
        window.innerWidth / window.innerHeight,
        0.1,
        1000
      );
      this.camera.position.set(0, 40, 100);
      this.camera.lookAt(new THREE.Vector3(0, 0, 0));
    },
    // 初始化场景
    initScene() {
      this.scene = new THREE.Scene();
    },
    // 初始化dat.GUI简化试验流程
    initGui() {
      // 声明一个保存需求修改的相关数据的对象
      this.settings = {
        positionX: 0,
        positionY: 5,
        positionZ: 0,
        rotationX: 0,
        rotationY: 0,
        rotationZ: 0,
        scaleX: 1,
        scaleY: 1,
        scaleZ: 1,
        translateX: 0,
        translateY: 0,
        translateZ: 0,
        translate: function() {
          // cube.translate(settings.translateX,settings.translateY,settings.translateZ);
          this.cube.translateX(this.settings.translateX);
          this.cube.translateY(this.settings.translateY);
          this.cube.translateZ(this.settings.translateZ);

          this.settings.positionX = this.cube.position.x;
          this.settings.positionY = this.cube.position.y;
          this.settings.positionZ = this.cube.position.z;
        },
        visible: true
      };
    },
    // 初始化灯光
    initLight() {
      this.scene.add(new THREE.AmbientLight(0x444444));
      this.light = new THREE.PointLight(0xffffff);
      this.light.position.set(15, 30, 10);
      // 告诉平行光需要开启阴影投射
      this.light.castShadow = true;

      this.scene.add(this.light);
    },
    // 初始化model
    initModel() {
      // 辅助工具
      var helper = new THREE.AxisHelper(10);
      this.scene.add(helper);

      // 立方体
      var cubeGeometry = new THREE.CubeGeometry(10, 10, 10);
      var cubeMaterial = new THREE.MeshLambertMaterial({ color: 0x00ffff });
      this.cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
      // 告诉立方体需要投射阴影
      this.cube.castShadow = true;
      this.scene.add(this.cube);
      // 底部平面
      var planeGeometry = new THREE.PlaneGeometry(100, 100);
      var planeMaterial = new THREE.MeshStandardMaterial({ color: 0xaaaaaa });
      var plane = new THREE.Mesh(planeGeometry, planeMaterial);
      plane.rotation.x = -0.5 * Math.PI;
      plane.position.y = -0;
      // 告诉底部平面需要接收阴影
      plane.receiveShadow = true;

      this.scene.add(plane);
    },
    // 用户交互插件 鼠标左键按住旋转，右键按住平移，滚轮缩放
    initControls() {
      this.controls = new OrbitControls(this.camera, this.renderer.domElement);

      // 如果使用animate方法时，将此函数删除
      // controls.addEventListener( 'change', render );
      // 使动画循环使用时阻尼或自转 意思是否有惯性
      this.controls.enableDamping = true;
      // 动态阻尼系数 就是鼠标拖拽旋转灵敏度
      // this.controls.dampingFactor = 0.25;
      // 是否可以缩放
      this.controls.enableZoom = true;
      // 是否自动旋转
      this.controls.autoRotate = false;
      // 设置相机距离原点的最远距离
      this.controls.minDistance = 100;
      // 设置相机距离原点的最远距离
      this.controls.maxDistance = 200;
      // 是否开启右键拖拽
      this.controls.enablePan = true;
    },
    render() {
      this.renderer.render(this.scene, this.camera);
    },
    // 窗口变动触发的函数
    onWindowResize() {
      this.camera.aspect = window.innerWidth / window.innerHeight;
      this.camera.updateProjectionMatrix();
      this.renderer.setSize(window.innerWidth, window.innerHeight);
    },
    animate() {
      // 更新控制器
      this.render();

      // 更新性能插件
      //   stats.update()

      // 更新相关位置
      this.cube.position.set(
        this.settings.positionX,
        this.settings.positionY,
        this.settings.positionZ
      );
      this.cube.scale.set(
        this.settings.scaleX,
        this.settings.scaleY,
        this.settings.scaleZ
      );
      this.cube.rotation.set(
        this.settings.rotationX,
        this.settings.rotationY,
        this.settings.rotationZ
      );
      this.cube.visible = this.settings.visible;

      this.controls.update();

      requestAnimationFrame(this.animate);
    },
    draw() {
      this.initGui();
      this.initRender();
      this.initScene();
      this.initCamera();
      this.initLight();
      this.initModel();
      this.initControls();
      //   this.initStats()
      this.animate();
      window.onresize = this.onWindowResize;
    }
    // render() {
    //   window.requestAnimationFrame(() => this.render())
    //   const box = this.scene.getObjectByName('box')
    //   // box.rotation.x += 0.01
    //   // box.rotation.y += 0.01
    //   // box.rotation.z += 0.01
    //   this.renderer.render(this.scene, this.camera)
    // }
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped></style>
